package com.wangmei.controller;

import com.wangmei.model.User;
import com.wangmei.model.UserExample;
import com.wangmei.pojo.UserSimplify;
import com.wangmei.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import unitTool.Dictionary;
import unitTool.EmptyTool;
import unitTool.JsonRsp;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.*;
import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {

    Logger log = LoggerFactory.getLogger(UserController.class);

    @Autowired
    public UserService userService;

    /**
     * 登录接口
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public JsonRsp login(@RequestParam("username") String username,
                         @RequestParam("password") String password,
                         HttpSession session) {
        ModelAndView mv = new ModelAndView();
        try {
            // 设置查询参数
            Map<String, Object> map = new HashMap<>();
            map.put("tel", username);
            map.put("email", username);
            map.put("istate", 0);
            List<User> users = userService.selectByTelOrEmail(map);

            // 判断用户是否存在
            if (EmptyTool.isEmpty(users))
                return JsonRsp.fail(101, "用户不存在");


            // 判断密码是否正确
            if (!users.get(0).getPassword().equals(password))
                return JsonRsp.fail(102, "密码错误");


            // 简化存储到Session的信息
            User user = users.get(0);
            UserSimplify us = new UserSimplify();
            BeanUtils.copyProperties(user, us);
            us.setUsername(username);
            session.setAttribute(Dictionary.SessionKey.CURRENT_USER, us);

            return JsonRsp.success(new HashMap<String, Object>());
        } catch (Exception e) {
            e.printStackTrace();
            return JsonRsp.fail(1000, "系统内部错误");

        }
    }

    /**
     * 获取当前登录用户
     */
    @RequestMapping(value = "/getLoginedUser", method = RequestMethod.GET)
    public JsonRsp getLoginedUser(HttpSession session) {
        try {
            Object obj = session.getAttribute(Dictionary.SessionKey.CURRENT_USER);
            if (null != obj)
                return JsonRsp.success(obj);

            return JsonRsp.fail(100, "无登录用户");
        } catch (Exception e) {
            e.printStackTrace();
            return JsonRsp.fail(1000, "系统内部错误");
        }
    }

    /**
     * 注册接口
     */
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public JsonRsp register(@RequestParam(value = "flag") int flag,
                            @RequestParam(value = "tel", required = false) String tel,
                            @RequestParam(value = "email", required = false) String email,
                            @RequestParam("password") String password,
                            @RequestParam(value = "relname", required = false) String relname,
                            @RequestParam(value = "keyidentity", required = false) String keyidentity,
                            @RequestParam("verifycode") String verifycode,
                            HttpSession session) {
        try {
            User newUser = new User();
            switch (flag) {
                // 手机注册
                case 0:
                    if (EmptyTool.isEmpty(tel))
                        return JsonRsp.fail(100, "手机号不能为空");

                    if (userExist(tel).getCode() == 100)
                        return JsonRsp.fail(100, "手机号已被注册");
                    newUser.setTel(tel);
                    break;
                // 邮箱注册
                case 1:
                    if (EmptyTool.isEmpty(email))
                        return JsonRsp.fail(100, "邮箱不能为空");

                    if (userExist(email).getCode() == 100)
                        return JsonRsp.fail(100, "邮箱已被注册");
                    newUser.setEmail(email);
                    break;
                default:
            }

            String code = (String) session.getAttribute(Dictionary.SessionKey.VERIFY_CODE);
            System.out.println(verifycode + "---------" + code + "-----------" + session.getId());
            if (EmptyTool.isEmpty(verifycode) || !verifycode.equalsIgnoreCase(code.toString()))
                return JsonRsp.fail(101, "验证码错误");

            newUser.setPassword(password);
            newUser.setRelname(relname);
            newUser.setKeyidentity(keyidentity);
            newUser.setRid(0);
            newUser.setIstate(0);
            newUser.setIslock(0);
            UserSimplify currentUser = (UserSimplify) session.getAttribute(Dictionary.SessionKey.CURRENT_USER);
            if (currentUser != null)
                newUser.setAdduser(currentUser.getUsername());
            newUser.setAddtime(new Date(System.currentTimeMillis()));

            return JsonRsp.success(userService.insertSelective(newUser));
        } catch (Exception e) {
            e.printStackTrace();
            return JsonRsp.fail(1000, "系统内部错误");
        }
    }

    /**
     * 获取登录验证码
     */
    @RequestMapping(value = "/getVerifyCode", method = RequestMethod.GET)
    public JsonRsp getVerifyCode(HttpServletRequest request, HttpServletResponse response) {
        try {
            VerifyCodeTool codeTool = new VerifyCodeTool();
            codeTool.getRandomVerifyCode(request, response);
            return JsonRsp.success(null);
        } catch (Exception e) {
            e.printStackTrace();
            return JsonRsp.fail(1000, "系统内部错误");
        }
    }

    /**
     * 根据用户名判断用户是否存在
     */
    @RequestMapping(value = "/userExist", method = RequestMethod.GET)
    public JsonRsp userExist(@RequestParam("username") String username) {
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("tel", username);
            map.put("email", username);
            List<User> users = userService.selectByTelOrEmail(map);
            if (EmptyTool.isEmpty(users))
                return JsonRsp.success("用户不存在");
            return JsonRsp.fail(100, "用户存在");
        } catch (Exception e) {
            e.printStackTrace();
            return JsonRsp.fail(1000, "系统内部错误");
        }
    }

    /**
     * 获取所有用户
     */
    @RequestMapping(value = "/getAllUsers", method = RequestMethod.GET)
    public JsonRsp getAllUsers() {
        try {
            UserExample user = new UserExample();
            return JsonRsp.success(userService.selectByExample(user));
        } catch (Exception e) {
            return JsonRsp.fail(1000, "系统内部错误");
        }
    }

    @RequestMapping(value = "/userExit", method = RequestMethod.GET)
    public JsonRsp userExit(HttpSession session) {
        try {
            session.removeAttribute(Dictionary.SessionKey.CURRENT_USER);
            return JsonRsp.success("用户退出");
        } catch (Exception e) {
            log.error("系统内部错误", e);
            return JsonRsp.fail(1000, "系统内部错误");
        }
    }

    @RequestMapping(value = "/changePassword", method = RequestMethod.POST)
    public JsonRsp changePassword(@RequestParam("uid") Integer uid,
                                  @RequestParam("oldPassword") String oldPassword,
                                  @RequestParam("newPassword") String newPassword) {
        try {
            if (!userService.selectByPrimaryKey(uid).getPassword().equals(oldPassword))
                return JsonRsp.fail(100, "原密码不正确");
            User user = new User();
            user.setUid(uid);
            user.setPassword(newPassword);

            return JsonRsp.success(userService.updateByPrimaryKeySelective(user));
        } catch (Exception e) {
            log.error("系统内部错误", e);
            return JsonRsp.fail(1000, "系统内部错误");
        }
    }

    class VerifyCodeTool {

        private String codeCharacter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
        public final int imgWidth = 95;
        public final int imgHeight = 25;
        public final int imgLine = 4;
        public final int codeNum = 4;
        private Random random = new Random();

        public void getRandomVerifyCode(HttpServletRequest request, HttpServletResponse response) {
            HttpSession session = request.getSession();
            System.out.println(session.getId());

            BufferedImage codeImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics g = codeImg.createGraphics();
            g.fillRect(0, 0, imgWidth, imgHeight);
            g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
            g.setColor(getRandomColor(110, 133));

            for (int i = 0; i < imgLine; i++) {
                drowLine(g);
            }

            String randomString = "";
            for (int i = 1; i <= codeNum; i++) {
                randomString = drowString(g, randomString, i);
            }

            session.removeAttribute(Dictionary.SessionKey.VERIFY_CODE);
            session.setAttribute(Dictionary.SessionKey.VERIFY_CODE, randomString);
            g.dispose();
            try {
                // 将内存中的图片通过流动形式输出到客户端
                ImageIO.write(codeImg, "JPEG", response.getOutputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public Font getFont() {
            return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
        }

        private String drowString(Graphics g, String randomString, int i) {
            g.setFont(getFont());
            g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
                    .nextInt(121)));

            String rand = getRandomString(random.nextInt(codeCharacter.length()));

            randomString += rand;
            g.translate(random.nextInt(3), random.nextInt(3));
            g.drawString(rand, 13 * i, 16);
            return randomString;
        }

        private String getRandomString(int num) {
            return String.valueOf(codeCharacter.charAt(num));
        }

        private void drowLine(Graphics g) {

            int x0 = random.nextInt(imgWidth - 13);
            int y0 = random.nextInt(imgHeight - 15);
            int x1 = x0 + random.nextInt(13);
            int y1 = y0 + random.nextInt(15);
            g.drawLine(x0, y0, x1, y1);
        }

        private Color getRandomColor(int fc, int bc) {
            if (fc > 255)
                fc = 255;
            if (bc > 255)
                bc = 255;
            int r = fc + random.nextInt(bc - fc - 16);
            int g = fc + random.nextInt(bc - fc - 14);
            int b = fc + random.nextInt(bc - fc - 18);
            return new Color(r, g, b);
        }

    }
}
